﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using LayeredArchitectureSample.DataTransferObjects;
using LayeredArchitectureSample.DomainModel;
using LayeredArchitectureSample.Infrastructure;
using LayeredArchitectureSample.ServiceContracts;

namespace LayeredArchitectureSample.Services
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
    [ExceptionMarshallingBehavior]
    public class TripManager : ITripManager
    {
        private readonly ITripRepository _tripRepository;

        public TripManager(ITripRepository tripRepository)
        {
            if (tripRepository == null) throw new ArgumentNullException("tripRepository");

            _tripRepository = tripRepository;
        }

        IEnumerable<TripDto> ITripManager.GetAll()
        {
            return _tripRepository.GetAll().Select(trip => new TripDto(trip)).ToList();
        }

        public TripDto CreateShippedTrip(RouteDto route, IEnumerable<WareUnitsCountedDto> waresToTake)
        {
            Trip newTrip =
                _tripRepository.AddNewTrip(DtoToRoute(route), waresToTake.Select(w=>new WareUnitsCounted(new Ware(w.Ware.Id, w.Ware.Code), w.Quantity)));

            return new TripDto(newTrip);
        }

        private static Route DtoToRoute(RouteDto route)
        {
            return new Route(route.Id, route.Waypoints.Select(w=>new Location(w.Id, w.Name)));
        }

        public TripDto MarkAsArrived(long tripId)
        {
            Trip trip = _tripRepository.GetTripById(tripId);

            trip.MarkAsArrivedToFinalDestination();

            _tripRepository.PersistChanges(trip);

            return new TripDto(_tripRepository.GetTripById(tripId));
        }
    }
}